<template>
	<view>
		<view class="container">
			<view class="top-dro zl-flex zl-row-between">
				<text class="zl-font-26 zl-color-white">如何使用声音克隆?</text>
				<view class="btn zl-flex zl-row-center" @click="check">
					<text>查看介绍</text>
				</view>
			</view>
			<view class="zl-flex">
				<view class="up_voice " @click="toWx()">
					<view class="tuijian"> 推荐 </view>
					<image class="zl-m-t-60" style="width: 90rpx;height: 90rpx;" src="/static/clone/wx.png" mode="">
					</image>
					<view class="zl-color-333 zl-font-30 zl-font-500 zl-m-t-34"> 微信上传语音 </view>
					<view class="zl-color-999 zl-font-22 zl-text-center zl-m-t-20"> 选择微信聊天记录里</br> 时长10秒以上的语音上传 </view>
					<view class="up_btn" style="background: #D2F8D1;border: 1rpx solid #09BB07;color: #09BB07;"> 去上传
					</view>
				</view>
				<view class="up_voice zl-m-l-30" @click="uploadVoice()">
					<image class="zl-m-t-60" style="width: 90rpx;height: 90rpx;" src="/static/clone/luzhi.png" mode="">
					</image>
					<view class="zl-color-333 zl-font-30 zl-font-500 zl-m-t-34"> 录制自己声音 </view>
					<view class="zl-color-999 zl-font-22 zl-text-center zl-m-t-20"> 点击录制语音，</br> 建议录制10-30秒内 </view>
					<view class="up_btn"> 去录制 </view>
				</view>
			</view>
			<view class="demand-tit zl-flex">
				<view class="line"></view>
				<view style="line-height: 43rpx;" class="zl-font-30 zl-color-000 zl-font-600 zl-m-l-12"> 声音克隆要求 </view>
			</view>
			<view class="demand-txt">
				<view class="txt-cell">
					<view class="label">
						文件大小
					</view>
					<view class="value">
						10MB以内
					</view>
				</view>
				<view class="txt-cell">
					<view class="label">
						音频时长
					</view>
					<view class="value">
						建议为 10s~30s的音频
					</view>
				</view>
				<view class="txt-cell">
					<view class="label">
						文件格式
					</view>
					<view class="value">
						mp3、m4a、wav
					</view>
				</view>
				<view class="txt-cell">
					<view class="label">
						录制环境
					</view>
					<view class="value">
						1.尽量在同一声学环境下录制，避免过于喧哗的背最音和噪音，音频非拼接而成。2.避免远场环境下录制,建议离麦克风50cm之内,并需要保持位置、距离稳定防止音量大小不一致。不要让讲话的气流正对麦克风，防止喷麦造成的噪音。3.尽量在自然对话状态下录制,对比刻意压低声线/呢喃获得的音色会更贴合本人。
					</view>
				</view>
				<view class="txt-cell">
					<view class="label">
						音频质量
					</view>
					<view class="value">
						1.必须仅含有一个人在说话,避免多个人同时说话。2.说话人发音及音质越清晰、复刻质量越高。如说话人喉音/声音底噪严重,则复刻音频喉音和底噪将会较为严重。3.录音时需要保持音量大小、语速稳定、注意断句、避免口腔噪音(如口水声)、杂音、混响等情况。结合最终使用场景与人设加入适当演绎避免朗读风格过于严重,并保持整体风格致。4.录音时尽量保持姿态稳定，减少不必要的肢体动作,椅子的响声、衣物的磨擦音、鼠标键
						盘的敲击声都是常见的人为噪声，需要格外注意细节。5.如口误无需终止录音,可停顿1~2秒后，继续录制即可。文案中所有文字不必追求一字不落地完成,可以接受丢字、填字,保持语句通畅即可。
					</view>
				</view>
				<view class="txt-cell">
					<view class="label">
						录制内容
					</view>
					<view class="value">
						建议在录音前熟悉文案，并确定好人设及演绎风格。尽量贴近复刻内容和主题，避免说话人韵律过干平淡,否则将得到较平的复刻效果。如需要复刻情绪韵律起伏较强的音频,请尽量输入表现力强的音频。尽量不要尝试复刻小孩或者老人的音频。
					</view>
				</view>
			</view>


		</view>
		<uni-popup :animation="false" ref="popup" type="center" background-color="#fff"
			border-radius="20rpx 20rpx 20rpx 20rpx">
			<view class=""
				style="width: 560rpx;height: auto;background-color: #fff;border-radius: 20rpx;padding:40rpx 30rpx;">
				<view class="" style="display: flex;justify-content: flex-end;width: 100%;">
					<image @click="close()" style="width: 34rpx;height: 34rpx;" src="/static/icon/pop_close.png"
						mode=""></image>
				</view>
				<view class="pro_title">上传进度</view>
				<view class="pros zl-m-t-20">
					<progress :percent="pro" show-info stroke-width="3" />
				</view>
				<view class="pros zl-m-t-20">
					<progress :percent="getPro()" show-info stroke-width="3" />
				</view>
				<view class="pro_des zl-m-t-20">正在上传 {{cur_count}}/{{pro_count}}</view>
			</view>
		</uni-popup>
		<uni-popup :animation="false" ref="tipspopup" type="center" background-color="#fff"
			border-radius="20rpx 20rpx 20rpx 20rpx" :is-mask-click="false">
			<view class="tip-box zl-flex-col zl-col-center">
				<view class="zl-color-000 zl-font-40 zl-font-600 "> 温馨提示</view>
				<view class="zl-color-666 zl-font-24 zl-m-t-30">
					在线录制音频可能会导致声音质量下降导致克隆声音效果不佳。为了保证最佳的声音效果，建议您先使用手机系统录音后，再通过微信上传语音文件。 </view>
				<view class="btn zl-m-t-42 zl-theme-btn" @click="useSure()"> 我已知晓，继续录音 </view>
			</view>
		</uni-popup>
		<uni-popup :animation="false" ref="popup3" type="center" background-color="#fff"
			border-radius="20rpx 20rpx 20rpx 20rpx" :is-mask-click="false">
			<view class="tip-box zl-flex-col zl-col-center">
				<view class="zl-color-000 zl-font-34 zl-font-bold zl-width-100 zl-text-center"
					style="position: relative;"> 使用者协议 <image @click="closePop()"
						style="width: 30rpx;height: 30rpx;position: absolute;right: -20rpx;top: 8rpx;"
						src="/static/icon/pop_close.png" mode=""></image>
				</view>
				<view class="zl-color-000 zl-font-26 zl-m-t-30 scroll-box">
					<text class="zl-font-bold ">本人在此授权并承诺:</text></br> 1、<text
						class="zl-font-bold underlined">本人向当前登录平台(以下称“本平台”)提供</text>
					<text>(包括但不限于通过线上上传、线下等方式提供)</text><text
						class="zl-font-bold">的数据</text>(包括但不限于文字、图片、视频、音频等各种形式的内容，以及其中包含的姓名、电话号码、身份证号码、脸型、五官、身体部位、人物动作、服饰妆容、声音、文字、台词、音乐、音频、视觉设计等所有组成部分，以下统称为“数据”)的<text
						class="zl-font-bold underlined">唯一权利人为本人或本人已取得全体权利人</text>(包括但不限于著作权人等知识产权人、肖像权人、声音权人、个人信息权人、所有权人等)的合法完整授权(包括但不限于:生物识别信息编辑权、复制权、翻译权、汇编权、信息网络传播权、改编权及制作衍生品、表演和展示的权利等)(本平台有权视情况要求本人提供相关授权文件);
					</br>2、无论数据来源于本人还是第三方， <text class="zl-font-bold underlined">数据所涉及的全体权利人均同意本人使用账号</text>
					(即本人注册本平台使用的手机号) <text
						class="zl-font-bold underlined">将数据用于声音制作、包含权利人肖像、声音等的视频模板(以下简称“视频模板”)制作及其衍生作品的制作、发布。 </text>
					<text class="zl-font-bold underlined">数据授权可能产生的商业价值分配纠纷或其他潜在的纠纷皆为本人与数据所涉权利人之间的问题，均由本人自行处理，与本平台无关。
					</text></br>
					<text class="zl-font-bold underlined">3、数据所涉及的全体权利人均已知悉并同意本平台提供的针对视频模板涉及个人数据的处理能力，包括:</text></br>
					<view class="zl-font-bold underlined">(1)姓名、电话号码、身份证号码，用于本人账号的实名认证。</br>
						(2)训练视频中的脸型、五官、身体部位、人物动作、服饰妆容，用于定制视频模板形象。</br> (3)训练音频，用于定制视频模板声音。</br>
						</br> 4、本人保证向本平台提供的数据均真实合法合规有效、不违背公序良俗且不侵犯任何人的合法权益(包括但不限于著作权等知识产权、个人隐私权、个人信息权、肖像权、声音权等)。
						</br>5、本人通过本平台从事或拟从事的行为属于合法合规正当的行为。本人不会利用本平台实施任何违反中华人民共和国法律法规政策、危害国家安全和利益、损害国家形象、侵害社会公共利益、扰乱经济和社会秩序、违反本平台规则(包括但不限于:用户协议、隐私政策)、违反公序良俗或侵害他人合法权益的行为，包括但不限于:隐瞒制作的内容为深度合成的情况;利用本平台制作、复制、发布、传播虚假内容、黄赌毒等违法违规内容、侵犯他人的合法权益的内容、歪曲或篡改原作者(或原人物，原权利人)思想或原作者(或原人物，原权利人)的意思表示的内容、降低原作者(或原人物，原权和人)社会评价的内容。</br>6、本人不得对素材、模板以及输出内容中的人物肖像(如有)以冒犯、侵权、违法等任何不当方式使用，不当方式包括但不限于:</br>(1)在色情图像或类似情形中使用;
						</br>(2)用于暗示人物参与不道德或非法行为; </br>(3)用于暗示人物遭受身体或精神衰弱、疾病等状况: </br>(4)用于政治性代言的行为;
						</br>(5)用于产品或服务代言的行为; </br>(6)导致人物社会评价降低的行为; </br>(7)其他可能对人物有冒犯或贬低的行为。
						</br>7、本平台有权对本人制作(或发布)的内容进行审核，但对本人制作(或发布)的任何内容均不承担任何明示或默示的保证，均不代表本平台观点或意见。</view>
					本平台有权根据相关证据结合《民法典》《信息网络传播权保护条例》等法律法规及本条款的规定对侵权信息或违法违规信息进行处理。 <view class="zl-font-bold underlined">
						</br>8、本人应自行对其提供的数据、利用本平台所从事的活动、通过本平台进行的活动、或利用制作内容所进行的活动所引起的一切后果承担全部责任，本平台的所有者、运营方及关联方对此不承担任何责任。</br>9、在任何情况下，本平台、本平台的所有者、运营方及关联方均不对任何间接性、后果性、惩戒性、偶然性、特殊性的损害，包括本人使用本平台服务而遭受的利润损失承担责任(即使本平台、本平台的所有者、运营方及关联方已被告知该等损失的可能性)</br>10、本平台有权在本人制作内容的合理位置、区域进行显著标识，提示深度合成情况，本人不得采用技术手段删除、篡改、隐匿深度合成标识。</br>11、本人违反上述条款的，本平台有权立即停止相关服务、删除相关数据(如:制作的结果)、终止服务或采取其他合理措施减少损失，并有权追究本人的违约责任等法律责任，也无需向本人退还支付的任何费用，并有权要求本人赔偿所有损失(包括但不限于直接损失、间接损失、商誉损害、律师费用、诉讼费、保全费、保全担保费、鉴定费、调查费、公证费和其他法律开支等一切维护权益的费用及本平台因此向第三方承担的赔偿款、和解/调解费等全部费用)。
						本人违反上述条款的，本平台还有权根据司法部门或监管部门的要求，向其提供本人在本平台注册的个人信息(姓名、电话号码、身份证号码)及向本平台提交/利用本平台生成的全部数据。
						</br>12、本人系具有完全民事行为能力的年满18周岁的成年人，完全理解上述条款的含义并同意遵守上述条款。</view>
				</view>
				<view class="btn zl-m-t-42 zl-theme-btn" @click="agree()"> 我已知晓并同意 </view>
			</view>
		</uni-popup>
	</view>
</template>
<script>
	export default {
		data() {
			return {
				oemName: getApp().globalData.oemName,
				file: {},
				pro: 0,
				pro_count: 0,
				cur_count: 0,
				playIng: false,
				startTime: 0,
				appid: getApp().globalData.appid,
				config: {}

			};
		},
		onLoad() {
			this.$refs.popup3.open();
			uni.request({
				url: 'https://szrjch5.zhim123.com/audit.json?time=' + new Date().getTime(),
				success: (res) => {
					if (res.statusCode === 200) {
						console.log(res.data);
						this.config = res.data[this.appid]
					}
				}
			})
		},
		methods: {
			uploadVoice() {
				this.$refs.tipspopup.open()
			},
			useSure() {
				this.$refs.tipspopup.close()
				uni.navigateTo({
					url: '/pages/clone/transcribeVoice'
				})
			},
			// 计算进度条比例
			getPro() {
				return Math.floor((this.pro_count <= 0 ? 0 : (this.cur_count / this.pro_count * 100)) * 100) / 100;
			},
			toWx() {
				wx.chooseMessageFile({
					count: 1, //默认100
					type: 'file',
					extension: ['mp3', 'MP3', 'aac', 'm4a', 'wav'],
					sourceType: ['album', 'camera'],
					success: res => {
						console.log(res);
						const tempFilePath = res.tempFiles[0].path;
						this.file.tempFilePath = tempFilePath;
						this.file.size = res.size;
						this.uploadAll(res.tempFiles)
					},
					fail: err => {
						console.log(err);
					}
				});
			},
			async uploadAll(list) {
				uni.showLoading({
					title: '上传中...'
				})
				for (let i = 0; i < list.length; i++) {
					this.cur_count = i + 1;
					var item = list[i];
					console.log(item);
					var suffix = item.path.substr(item.path.lastIndexOf("."));
					var fileName = new Date().getTime() + '_' + this.$util.randomString(8) + suffix;
					let gs = ''
					let Index = item.path.lastIndexOf(".");
					gs = item.path.substr(Index + 1).toLowerCase();
					if (gs !== "mp3" && gs !== "m4a" && gs !== "wav") {
						this.$util.msg('第' + (i + 1) + '个素材格式不支持！');
						await new Promise((resolve, reject) => {
							setTimeout(() => {
								resolve({});
							}, 2300);
						});
						continue;
					}
					if (item.size > 1024 * 1024 * 20) {
						this.$util.msg(`第${i+1}个文件超出大小，请上传低于20兆的文件`)
						await new Promise((resolve, reject) => {
							setTimeout(() => {
								resolve({});
							}, 2300);
						});
						continue;
					}
					var signRes = undefined;
					try {
						signRes = await this.api.clone.applyuploadvoice({
							fileName: fileName,
						});
						if (signRes.code != 0) {
							// #ifdef MP-WEIXIN
							wx.reportEvent("media_upload", {
								code: signRes.code,
								msg: signRes.msg
							})
							// #endif
							this.$util.msg(signRes.msg);
							// uni.hideLoading()
							return;
						}
					} catch (e) {
						//TODO handle the exception
						// #ifdef MP-WEIXIN
						wx.reportEvent("media_upload", {
							exception: JSON.stringify(e)
						})
						// #endif
						this.$util.msg('上传初始化失败！');
						// uni.hideLoading()
						return;
					}
					if (!signRes || !signRes.data) {
						// #ifdef MP-WEIXIN
						wx.reportEvent("media_upload", {
							api_exception: '获取签名失败！'
						})
						// #endif
						this.$util.msg('上传初始化失败！');
						// uni.hideLoading()
						return;
					}
					var sign = signRes.data;
					try {
						var uploadRes = await this.upload(sign, item.path);
						console.log(uploadRes, '上传文件结果');
						getApp().globalData.temp_audio = uploadRes
						uni.navigateTo({
							url: '/pages/clone/upVoice'
						})
					} catch (e) {
						this.$util.msg('第' + (i + 1) + '个音频，' + e.message);
						// uni.hideLoading()
						await new Promise((resolve, reject) => {
							setTimeout(() => {
								resolve({});
							}, 2300);
						});
					}
					if (i < list.length - 1) {
						uni.hideLoading()
						await new Promise((resolve, reject) => {
							setTimeout(() => {
								resolve({});
							}, 1000);
						});
					}
				}
				uni.hideLoading()
			},
			async upload(sign, tempFilePath) {
				return await new Promise((resolve, reject) => {
					var task = uni.uploadFile({
						url: sign.host,
						filePath: tempFilePath,
						fileType: 'audio',
						name: 'file',
						formData: sign.formData,
						timeout: 3600000,
						success: (res) => {
							console.log(res);
							if (res.statusCode === 200) {
								try {
									let data = JSON.parse(res.data)
									if (data.code === 0) {
										resolve(data.data);
									} else {
										reject(new Error(data.msg))
									}
								} catch (e) {
									reject(new Error('解析上传结果失败！'))
								}
							} else {
								reject(new Error('上传失败！'));
							}
						},
						fail: (err) => {
							// #ifdef MP-WEIXIN
							wx.reportEvent("media_upload", {
								aliyun_exception: JSON.stringify(err),
							})
							// #endif
							reject(new Error('上传失败！'));
						}
					});
					task.onProgressUpdate((pro) => {
						this.pro = pro.progress;
						// console.log(this.pro);
					});
				});
			},
			closePop() {
				uni.navigateBack()
			},
			agree() {
				this.$refs.popup3.close()
			},
			check() {
				let url =	'https://oop-zl-szr.oss-cn-hangzhou.aliyuncs.com/static/'+getApp().globalData.jiaochengUrl2+'.mp4'
				if (this.config.isAudit) {
					this.$util.toWebView('https://szrjch5.zhim123.com/pages/learn/page3')
				} else {
					this.$util.toWebView(
						`https://szrjch5.zhim123.com/pages/video/index?url=${encodeURIComponent(url)}&title=教学视频`
					)
				}
			}
		}
	}
</script>
<style lang="scss" scoped>
	.container {
		padding: 40rpx 30rpx;
	}

	.top-dro {
		border-radius: 20rpx;
		width: 690rpx;
		height: 90rpx;
		// background: url("") no-repeat;
		// background-size: 100% 100%;
		margin: 0 auto 50rpx;
		padding: 0 30rpx;
		background-color: #000;
		// box-shadow: 0rpx 26rpx 30rpx 0rpx rgba(55, 58, 167, 0.24);

		.btn {
			width: 140rpx;
			height: 46rpx;
			border-radius: 6rpx;
			border: 1rpx solid #ffffff;
			font-size: 22rpx;
			font-weight: 500;
			color: #ffffff;

			image {
				width: 8rpx;
				height: 16rpx;
				margin-left: 5rpx;
			}
		}
	}


	.up_voice {
		position: relative;
		display: flex;
		flex-direction: column;
		align-items: center;
		width: 330rpx;
		height: 456rpx;
		background: #FFFFFF;
		border-radius: 20rpx;

		.tuijian {
			position: absolute;
			top: 0;
			left: 0;
			border-radius: 20rpx 0 20rpx 0;
			background-color: red;
			color: #fff;
			font-size: 22rpx;
			padding: 6rpx 20rpx;
		}

		.up_btn {
			width: 170rpx;
			height: 56rpx;
			background: #FAE4D2;
			border-radius: 10rpx;
			border: 1rpx solid #ECBA93;
			font-weight: 500;
			font-size: 24rpx;
			color: #EC6500;
			margin-top: 50rpx;
			text-align: center;
			line-height: 56rpx;
		}
	}

	.demand-tit {
		margin-top: 40rpx;

		.line {
			width: 6rpx;
			height: 28rpx;
			background: #EB5E00;
			border-radius: 3rpx;
		}
	}

	.demand-txt {
		margin-top: 30rpx;

		.txt-cell {
			display: flex;
			font-size: 28rpx;
			padding: 16rpx 2rpx;
			border-bottom: 1rpx solid #ccc;


			.label {
				color: #747475;
				width: 160rpx;
				font-weight: 600;
			}

			.value {
				width: calc(100% - 160rpx);
				color: #999;
				font-weight: 500;
			}
		}
	}

	.tip-box {
		width: 600rpx;
		background: #FFFFFF;
		border-radius: 18rpx;
		padding: 70rpx 60rpx 58rpx;
		position: absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -60%);

		.btn {
			display: flex;
			align-items: center;
			justify-content: center;
			width: 400rpx;
			height: 88rpx;
			border-radius: 44rpx;
		}

		.cancelbtn {
			background: #EEEEEE;
			font-weight: 600;
			font-size: 28rpx;
			color: #000;
		}

		.sure-btn {
			background: linear-gradient(90deg, #5493DF 0%, #144FC3 100%);
			box-shadow: 0rpx 10rpx 20rpx 0rpx rgba(66, 106, 171, 0.29);
			color: #fff;
		}
	}

	.scroll-box {
		height: 700rpx;
		overflow-y: scroll;
	}

	::-webkit-scrollbar {
		height: 0;
	}

	.underlined {
		text-decoration: underline;
	}
</style>